package com.ikas.ai.server.module.data.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageInfo;
import com.ikas.ai.enums.MeteTypeEnum;
import com.ikas.ai.server.module.data.model.BaseMete;
import com.ikas.ai.server.module.data.model.SimplifyRealDataHis;
import com.ikas.ai.server.module.data.model.doris.DorisYcData;
import com.ikas.ai.server.module.data.model.doris.DorisYxData;
import com.ikas.ai.server.module.data.model.dto.DataTdQueryDto;
import com.ikas.ai.server.module.data.model.dto.RealDataHis;
import com.ikas.ai.server.module.data.tdDao.TdDataHisMapper;
import com.ikas.ai.utils.CollectionUtil;
import com.ikas.ai.utils.DateTimeUtil;
import com.ikas.ai.utils.PageExUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 数据服务类
 * @Author: qi.yilai
 * @Date: 2023/2/3 16:31
 * @Version: 1.0.0
 **/
@Slf4j
@Service
public class DataService {

    private static final String IKAS_PREFIX = "ikas_";

    @Resource
    private TdDataHisMapper dataHisTdMapper;

    @Resource
    private DorisYxDataService dorisYxDataService;

    @Resource
    private DorisYcDataService dorisYcDataService;

    @Resource
    private BaseMeteService baseMeteService;

    /**
     * 获取测点值
     *
     * @param queryDto 入参
     * @return 最新测点数据
     */
    public PageInfo<SimplifyRealDataHis> getDataMetesFromTd(DataTdQueryDto queryDto) {
        String machineNo = queryDto.getMachineNo();
        String meteCode = queryDto.getMeteCode();
        Long meteId = queryDto.getMeteId();
        Assert.notBlank(meteCode, "meteCode不能为空");
        //测点有效值
        BaseMete baseMete = baseMeteService.selectByMachNoMeteCodeMeteId(machineNo, meteCode, meteId);
        if (null == baseMete) {
            return new PageInfo<>();
        }
        meteId = Objects.isNull(meteId) ? baseMete.getMeteId() : meteId;
        List<SimplifyRealDataHis> list = getPageOfDataListFromTd(
                queryDto, meteId, baseMete.getMeteType(), baseMete.getValidMeteValue());
        return new PageInfo<>(list);
    }

    /**
     * 从tdEngine中获取数据-分页
     *
     * @param queryDto       入参对象
     * @param meteId         测点id
     * @param meteType       测点类型
     * @param validMeteValue 测点有效值
     * @return list of SimplifyRealDataHis
     */
    private List<SimplifyRealDataHis> getPageOfDataListFromTd(DataTdQueryDto queryDto,
                                                              Long meteId,
                                                              Integer meteType,
                                                              Integer validMeteValue) {
        if (Objects.isNull(meteId)) {
            return new ArrayList<>();
        }
        if (MeteTypeEnum.YX.getNum().equals(meteType)) {
            queryDto.setValidMeteValue(validMeteValue);
        }
        if (queryDto.getLatestNumType() != null && queryDto.getLatestNumType().getNum() != null) {
            //不进行总数计算了，因为tdEngine不支持三层及以上的嵌套查询
            PageExUtil.configPageHelper(queryDto, false);
        } else {
            PageExUtil.configPageHelper(queryDto);
        }
        //从子表中获取
        return getRealDataHisFromSonTable(queryDto, meteId, meteType);
    }

    /**
     * 从tdengine的子表获取数据
     * @param queryDto 查询条件
     * @param meteId 测点id
     * @param meteType 测点类型
     * @return list of SimplifyRealDataHis
     */
    public List<SimplifyRealDataHis> getRealDataHisFromSonTable(DataTdQueryDto queryDto, Long meteId, Integer meteType) {
        String tableName = IKAS_PREFIX
                + MeteTypeEnum.getEnName(meteType)
                + meteId;
        try {
            return dataHisTdMapper.getDataHisListByMeteIdQuery(tableName, queryDto);
        } catch (Exception e) {
            log.error("getRealDataHisFromSonTable error:{}", e.getMessage());
            return new ArrayList<>();
        }
    }

    /**
     * 获取测点值
     *
     * @param meteCode 测点编号
     * @return 最新测点数据
     */
    public DorisYxData getLatestOneDataMete(String machineNo, String meteCode, Long meteId) {
        Assert.notBlank(meteCode, "测点编号不能为空");
        //测点有效值
        BaseMete baseMete = baseMeteService.selectByMachNoMeteCodeMeteId(machineNo, meteCode, meteId);
        if (null == baseMete) {
            return null;
        }
        meteId = Objects.isNull(meteId) ? baseMete.getMeteId() : meteId;
        return getDataByMeteIdFromDoris(meteId, baseMete.getMeteType(), baseMete.getValidMeteValue());
    }

    private DorisYxData getDataByMeteIdFromDoris(Long meteId, Integer meteType, Integer validMeteValue) {
        if (Objects.isNull(meteId)) {
            return null;
        }
        if (MeteTypeEnum.YX.getNum().equals(meteType)) {
            String validValue = validMeteValue == null ? "" : validMeteValue.toString();
            return getYxFromDoris(meteId, validValue);
        } else {
            DorisYcData ycData = dorisYcDataService.getByMeteId(meteId);
            return ycData == null ? null : BeanUtil.copyProperties(ycData, DorisYxData.class);
        }
    }

    private DorisYxData getYxFromDoris(Long meteId, String validValue) {
        List<DorisYxData> yxs = dorisYxDataService.getYxsByMeteId(meteId);
        yxs = yxs.stream()
                .filter(yx -> validValue.equals(yx.getValue()))
                .collect(Collectors.toList());
        return CollectionUtil.isEmpty(yxs) ? null : yxs.get(0);
    }


}
